package bdhub.littletail.app.account.controller;

import android.annotation.SuppressLint;
import android.text.TextUtils;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Lists;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import bdhub.littletail.app.LittleTailApplication;
import bdhub.littletail.app.account.model.OnGetUserListener;
import bdhub.littletail.app.account.model.User;
import bdhub.littletail.app.config.NetworkConfig;
import bdhub.littletail.app.utils.Storage;
import bdhub.littletail.lib.utils.log.CLog;
import se.emilsjolander.sprinkles.Query;

public class UserManager {

	private static UserManager INSTANCE;

	/**
	 * 监听器列表锁
	 */
	private static final Object REQUEST_LOCK = new Object();

	private String mToken;
	private User mCurrentUser;
	/**
	 * 这个变量缓存了用户信息，只要加载了通讯录，缓存有所有的用户信息（不知道性能会不会有问题）<br />
	 * 用户信息有更新时，都应该同步到这里<br />
	 * 同样，需要取用户信息时，都应先访问这里。
	 */
	@SuppressLint("UseSparseArrays")
	private static HashMap<Long, User> CACHE_USERS = new HashMap<Long, User>();
	private boolean mIsWaitForLogin = false;
	private static boolean mIsGoingToSignIn = false;
	
	private ArrayList<User> mRecommandedUsersCache;
	
	public void addRecommandedUser(User user) {
		//给缓存设个上限
		if (mRecommandedUsersCache.size() < 20) {
			if (null == mRecommandedUsersCache) {
				mRecommandedUsersCache = Lists.newArrayList();
			}
			mRecommandedUsersCache.add(user);
		}
	}
	
	public void addRecommandedUsers(List<User> users, boolean replace) {
		if (null == mRecommandedUsersCache) {
			mRecommandedUsersCache = Lists.newArrayList();
		} else if (replace) {
			mRecommandedUsersCache.clear();
		}
		if (null != users) {
			mRecommandedUsersCache.addAll(users);
		}
	}
	
	public ArrayList<User> getRecommandedUsers() {
		if (null == mRecommandedUsersCache) {
			mRecommandedUsersCache = Lists.newArrayList();
		}
		return mRecommandedUsersCache;
	}

	private UserManager() {

	}

	public static UserManager getInstance() {
		if (null == INSTANCE) {
			synchronized (UserManager.class) {
				if (null == INSTANCE) {
					INSTANCE = new UserManager();
					// 初始化用户信息
					INSTANCE.initUserFromCache();
				}
			}
		}
		return INSTANCE;
	}

	private static void initUserDatabase(long userId) {
		LittleTailApplication.sharedInstance().initDatabase(userId);
	}

	/**
	 * 获取当前用户<br />
	 * 如果用户未登录则为 null
	 *
	 * @return
	 */
	public static User getCurrentUser() {
		return getInstance().getUser();
	}
	
	/**
	 * 获取当前用户 ID，如果没有当前用户，不会报错，而是返回 0
	 *
	 * @return
	 */
	public static long getCurrentUserId() {
		User user = getInstance().getUser();
		if (null != user) {
			return user.getId();
		}
		return 0;
	}

	private User getUser() {
		if (null == mCurrentUser) {
			initUserFromCache();
		}
		return mCurrentUser;
	}
	
	//这个方法要使用 synchronized，不然会多次初始化，getUser() 则不需要 synchronized，提高效率。
	private synchronized void initUserFromCache() {
		if (null != mCurrentUser) {
			return;
		}
		JSONObject token = Storage.getInstance().getToken();
		if (null != token) {
			long userId = token
					.getLongValue(NetworkConfig.PARAM_ACCOUNT_UID);
			initUserDatabase(userId);
			
			//查询数据库时，有时会报这些错：
			//java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
			//java.lang.RuntimeException: java.lang.NullPointerException at se.emilsjolander.sprinkles.Utils.getResultFromCursor(Native Method)
			try {
				mCurrentUser = Query.one(User.class,
						"select * from Users where id=?", userId).get();
				setCurrentUser(mCurrentUser);
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (NullPointerException e)  {
				e.printStackTrace();
			}
		}
	}

	public static synchronized void setCurrentUser(User user) {
		CLog.show("setCurrentUser：" + user);
		User oldUser = getInstance().mCurrentUser;
		getInstance().mCurrentUser = user;
		//用户未完善资料时，可以初始化数据库，但不去初始化 IM 那些。
		if (null != user) {
			if (null == oldUser || oldUser.getId() != user.getId()) {
				initUserDatabase(user.getId());
			}
			updateUser(user);
			if (hasProfile()) {
//				mStateChangedHandler.onAccountReady();
			}
		}
	}

	/**
	 * 更新本地用户信息
	 *
	 * @param user
	 */
	public static void updateUser(User user) {
		//user.save();
		CACHE_USERS.put(user.getId(), user);
		user.saveAsync();
		if (user.getId() == getCurrentUserId()) {
			getInstance().mCurrentUser = user;
		}
	}

	public static synchronized void setToken(JSONObject data) {
		getInstance().mToken = data.getString(NetworkConfig.PARAM_ACCOUNT_TOKEN);
		Storage.getInstance().setToken(data);
	}

	public static String getToken() {
		if (null == getInstance().mToken) {
			synchronized (UserManager.class) {
				if (null == getInstance().mToken) {
					JSONObject tokenData = Storage.getInstance().getToken();
					if (null != tokenData) {
						getInstance().mToken = tokenData
								.getString(NetworkConfig.PARAM_ACCOUNT_TOKEN);
					}
				}
			}
		}
		return getInstance().mToken;
	}

	/**
	 * 判断用户是否完善必要的资料
	 *
	 * @return
	 */
	public static boolean hasProfile() {
		User currentUser = UserManager.getCurrentUser();
		if (null != currentUser
				&& !TextUtils.isEmpty(currentUser.getNickName())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 根据用户 id 获取用户信息<br />
	 * 仅在本地查询
	 *
	 * @param id
	 * @return user
	 */
	public static User getUser(long id) {
		if (0 == id) {
			return null;
		}
		User user = getUserFromLocal(id);
		if (null == user) {
			fetchUserInfoFromServer(id);
		}
		return user;
	}

	/**
	 * 根据用户 id 获取用户信息<br />
	 * 如果本地没用户信息，则会向服务器查询。
	 *
	 * @param id
	 * @return user
	 */
	public static void getUser(long id, OnGetUserListener listener) {
		if (0 == id || null == listener) {
			return;
		}
		User user = getUserFromLocal(id);
		if (null != user) {
			listener.onSuccessed(user);
		} else {
			fetchUserInfoFromServer(id, listener);
		}
	}

	private static void fetchUserInfoFromServer(long id) {
		// 从服务端拉取用户信息
		fetchUserInfoFromServer(id, null);
	}

	private static void fetchUserInfoFromServer(long id, OnGetUserListener listener) {
		// 从服务端拉取用户信息
	}

	private static User getUserFromLocal(long id) {
		User user = CACHE_USERS.get(id);
		if (null == user) {
			//java.lang.RuntimeException: java.lang.NullPointerException
			//at se.emilsjolander.sprinkles.Utils.getResultFromCursor(Native Method)
			try {
				user = Query.one(User.class, "sql语句", id).get();
			} catch (NullPointerException e) {
				e.printStackTrace();
			}
			if (null != user) {
				CACHE_USERS.put(id, user);
			}
		}
		return user;
	}


	public interface IAccountStateChangedHandler {

		/**
		 * 用户准备就绪（包括登录成功，或者是从本地读取登录态成功）
		 */
		public abstract void onAccountReady();

		/**
		 * 退出登录
		 */
		public abstract void onAccountSignout();
	}
}
